#pragma once
#include "CDependencyObject.h"
class CDependencyObject;

class CREATEPARAMETERS;
typedef void (__stdcall *PFNOwnerRenderChangedHandler)(CDependencyObject *, DirtyFlags::Value);
typedef void (__stdcall *PFNNewOwnerRenderChangedHandler)(CDependencyObject *, DirtyFlags::Value);
typedef void (__stdcall *PFNOwnerDirtyFlag)(CDependencyObject *, DirtyFlags::Value);


class CWeakRef;


class CCollection :
	public CDependencyObject
{

protected: 
	CCollection(XINT32 itemSize);
	virtual ~CCollection();
public: 
	static HRESULT Create(CDependencyObject * * ppObject, CREATEPARAMETERS * pCreate); 
	virtual XBOOL ContainsDependencyObject();
	virtual XUINT32 GetCount();

protected: 
	virtual HRESULT SetOwner(CDependencyObject * pNewOwner, XBOOL fOwnerIsFallback, PFNNewOwnerRenderChangedHandler  * pfnNewOwnerRenderChangedHandler);
public: 
	virtual HRESULT SetOwner(CDependencyObject * pOwner, PFNOwnerDirtyFlag  * pfnOwnerDirtyFlag);
	virtual HRESULT SetAndPropagateOwner(CDependencyObject * pOwner, PFNOwnerDirtyFlag  * pfnOwnerDirtyFlag);
	virtual HRESULT PropagateOwnerInfo(CDependencyObject * pOwner, CDependencyObject * pOldOwner);
	static HRESULT ValidateParams(XUINT32 cArgsExpected, struct Xcp_IDependencyObject * pObject, XUINT32 cArgs, CValue * ppArgs);
	static HRESULT GetItemCount(struct Xcp_IDependencyObject * pObject, XUINT32 cArgs, CValue * ppArgs, CValue * pResult);
	static HRESULT Add(struct Xcp_IDependencyObject * pObject, XUINT32 cArgs, CValue * ppArgs, CValue * pResult);
	virtual HRESULT Clear();
	static HRESULT Clear(struct Xcp_IDependencyObject *, XUINT32, CValue *, CValue *);
	static HRESULT Count(struct Xcp_IDependencyObject * pObject, XUINT32 cArgs, CValue * ppArgs, CValue * pResult);
	virtual void * GetItem(XUINT32 index) = 0;
	static HRESULT GetItem(struct Xcp_IDependencyObject * pObject, XUINT32 index, CValue * pResult);
	static HRESULT InsertDO(struct Xcp_IDependencyObject * pObject, XUINT32 nIndex, CValue & value);

	virtual void * Remove(CValue & value);

	static HRESULT Remove(struct Xcp_IDependencyObject * pObject, CValue * pValue, XBOOL * pResult);
	static HRESULT Remove(struct Xcp_IDependencyObject * pObject, XUINT32 cArgs, CValue * ppArgs, CValue * pResult);

	virtual HRESULT IndexOf(CValue & value, XINT32 * pIndex);
	static HRESULT IndexOf(struct Xcp_IDependencyObject *, XUINT32, CValue *, CValue *);
	virtual void * RemoveAt(XUINT32 nIndex);
	HRESULT RemoveAt(XUINT32 nIndex, void * * ppRes);
	virtual HRESULT GetCollection(void * * ppCollection);
	virtual HRESULT Append(CValue &, XUINT32 *) = 0;
	virtual HRESULT Insert(XUINT32, CValue &) = 0;
	virtual HRESULT Move(XINT32, XINT32) = 0;
	void SetAffectsOwnerMeasure(XUINT32 value);
	void SetAffectsOwnerArrange(XUINT32 value);
	void Lock();
	void Unlock();
	XBOOL IsLocked();
	HRESULT FailIfLocked();
protected: 
	virtual HRESULT Broaden();
	virtual HRESULT Flatten(XINT32 bReserve);
	virtual HRESULT Neat(XINT32 bBreak);
	virtual HRESULT Tidy(XINT32 bBreak);
	virtual XUINT8 * GetFlattened() = 0;
	virtual void SetFlattened(XUINT8 *) = 0;
	virtual XUINT8 * * GetBlocks() = 0;
	virtual void SetBlocks(XUINT8 * *) = 0;
	virtual XBOOL NeedsOwnerInfo();
	HRESULT EnsureSpaceForAppend();
	void ItemToCValue(CValue * pResult, void * pItem, bool fDeleteValueObject, bool fManaged);
	virtual HRESULT Destroy();
	CDependencyObject * const GetOwner();
	virtual void NWPropagateDirtyFlag(enum DirtyFlags::Value flags);
	virtual HRESULT OnAddToCollection(const CValue & value);
	virtual HRESULT OnRemoveFromCollection(const CValue & value, XINT32 iPreviousIndex);
	virtual void OnRemovingDependencyObject(CDependencyObject * pDO);
	virtual HRESULT OnClear();
private: 
	virtual void ReleaseItem(void *) = 0;


	XUINT32 m_nObject;
	struct
	{
		XBOOL m_fOwnerIsFallback:1;
		XBOOL m_fAffectsOwnerMeasure:1;
		XBOOL m_fAffectsOwnerArrange:1;
	};

	PFNOwnerRenderChangedHandler  * m_pfnOwnerRenderChangedHandler;
private: 
	struct
	{
		XUINT32 m_nItemSize:5;
	};
	
	XUINT32 m_cLock;
	CWeakRef * m_pOwner;


};


